use std::future::{ready, Ready};

use actix_web::middleware::ErrorHandlerResponse;
use actix_web::{
    dev::{self, forward_ready, Service, ServiceRequest, ServiceResponse, Transform},
    http::header,
    Error, HttpResponse, Result,
};
use futures_util::future::LocalBoxFuture;
use serde_json::{json, Value};
use std::collections::HashMap;
use actix_session::{config::PersistentSession, storage::CookieSessionStore, SessionMiddleware};

// 权限控制中间件
pub struct Rule;

// Middleware factory is `Transform` trait
// `S` - type of the next service
// `B` - type of response's body
impl<S, B> Transform<S, ServiceRequest> for Rule
where
    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
    S::Future: 'static,
    B: 'static,
{
    type Response = ServiceResponse<B>;
    type Error = Error;
    type InitError = ();
    type Transform = RuleMiddleware<S>;
    type Future = Ready<Result<Self::Transform, Self::InitError>>;

    fn new_transform(&self, service: S) -> Self::Future {
        ready(Ok(RuleMiddleware { service }))
    }
}

pub struct RuleMiddleware<S> {
    service: S,
}

impl<S, B> Service<ServiceRequest> for RuleMiddleware<S>
where
    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
    S::Future: 'static,
    B: 'static,
{
    type Response = ServiceResponse<B>;
    type Error = Error;
    type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;

    forward_ready!(service);

    fn call(&self, req: ServiceRequest) -> Self::Future { 

        log::debug!("我是一个拦截器，你的地址: {}", req.path()); 

        let fut = self.service.call(req);

        Box::pin(async move { 

            let res = fut.await?; 

            log::debug!("哈哈，拦截ok");
            Ok(res)
        })
    }
} 